观察者模式

观察者模式又称监听者模式,它广泛应用在图形化编程中。
实现观察者模式比较直观的一种是使用“注册、通知、撤销注册”的形式:
(1)注册
观察者将自己注册到目标对象中,目标对象将观察者放在一个容器里。为防止观察者重复,一般用HashSet来保存观察者的引用(Set集合无序、不重复)。
(2)通知
目标对象发生了某种变化(如按钮被单击),从容器中得到所有注册过的观察者,将变化通知给观察者。
(3)撤销注册
观察者告诉目标要撤销观察,目标间观察者从容器中移除。所以观察者接口中需要有cancelObserve()方法,方法体中得到目标的容器,并去掉当前观察者。

1
2
3
4
5
//观察者(抽象类)
interface Observer{
public void update(Product p);
public void cancelProduct(Product p);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//具体观察者
public WebObserver implements Observer{
public void update(Product p){
System.out.println("更新页面价格" + p.getName() + p.getPrice());
}
pulic void cancelProduct(Product p){
p.getObservers().remove(this);
}
}
public MailObserver implements Observer{
public void update(Product p){
System.out.println("为所有会员发送价格变化信息" + p.getName() + p.getPrice());
}
pulic void cancelProduct(Product p){
p.getObservers().remove(this);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//商品类(具体类)
public class Product{
private String name;
private double price;
private HashSet<Observer> observers = new HashSet<>();
public Product(String name, double price){
this.name = name;
this.price = price;
observers = new HashSet<Observer>; //虽然没有传入参数,但也在构造器中初始化
}
public void addObserver(Observer obs){
observers.add(obs);
}
public void notifyObservers(){
for(Observer obs : observers){
obs.update(this);
}
}
//getter和setter方法
public String getName(){
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice(){
return price;
}
public void setPrice(double price){
this.price = price;
notifyObservers(); //价格变动通知所有观察者
}
public HashSet<Obsrever> getObservers(){
return observers;
}
public void setObservers(HashSet<Observer> observers) {
this.observers = observers;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
//主类
public class ObserverTest{
public static void main(Stirng[] args){
Product p = new Product("《Java》", 100);//创建一个商品
Observer ob1 = new Observer();//new观察者
Observer ob2 = new Observer();
p.addObserver(ob1);//注册观察者
p.addObserver(ob2);
p.setPrice(80);//修改商品价格,同时会通知所有观察者
ob1.cancelObserve(p);//取消观察者对p的观察
p.setPrice();//再次修改价格
}
}